home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / demos / OpenGL / insect / insect.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  23KB  |  1,096 lines

  1. /*
  2.  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED 
  4.  * Permission to use, copy, modify, and distribute this software for 
  5.  * any purpose and without fee is hereby granted, provided that the above
  6.  * copyright notice appear in all copies and that both the copyright notice
  7.  * and this permission notice appear in supporting documentation, and that 
  8.  * the name of Silicon Graphics, Inc. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission. 
  11.  *
  12.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  16.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  21.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  * 
  25.  * US Government Users Restricted Rights 
  26.  * Use, duplication, or disclosure by the Government is subject to
  27.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29.  * clause at DFARS 252.227-7013 and/or in similar or successor
  30.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  31.  * Unpublished-- rights reserved under the copyright laws of the
  32.  * United States.  Contractor/manufacturer is Silicon Graphics,
  33.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  34.  *
  35.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  36.  */
  37.  
  38. #undef FLAT_SHADING
  39.  
  40. #include <stdio.h>
  41. #include <string.h>
  42. #include <math.h>
  43. #include <GL/gl.h>
  44. #include "gl42ogl.h"
  45. #include "tk.h"
  46. #include "insect.h"
  47. #include "insectco.h"
  48.  
  49. GLushort ls = 0xaaaa;
  50.  
  51.  
  52. unsigned char   halftone[] = {
  53.     0xAA, 0xAA,    0xAA, 0xAA,
  54.     0x55, 0x55,    0x55, 0x55,
  55.     0xAA, 0xAA,    0xAA, 0xAA,
  56.     0x55, 0x55,    0x55, 0x55,
  57.     0xAA, 0xAA,    0xAA, 0xAA,
  58.     0x55, 0x55,    0x55, 0x55,
  59.     0xAA, 0xAA,    0xAA, 0xAA,
  60.     0x55, 0x55,    0x55, 0x55,
  61.  
  62.     0xAA, 0xAA,    0xAA, 0xAA,
  63.     0x55, 0x55,    0x55, 0x55,
  64.     0xAA, 0xAA,    0xAA, 0xAA,
  65.     0x55, 0x55,    0x55, 0x55,
  66.     0xAA, 0xAA,    0xAA, 0xAA,
  67.     0x55, 0x55,    0x55, 0x55,
  68.     0xAA, 0xAA,    0xAA, 0xAA,
  69.     0x55, 0x55,    0x55, 0x55,
  70.  
  71.     0xAA, 0xAA,    0xAA, 0xAA,
  72.     0x55, 0x55,    0x55, 0x55,
  73.     0xAA, 0xAA,    0xAA, 0xAA,
  74.     0x55, 0x55,    0x55, 0x55,
  75.     0xAA, 0xAA,    0xAA, 0xAA,
  76.     0x55, 0x55,    0x55, 0x55,
  77.     0xAA, 0xAA,    0xAA, 0xAA,
  78.     0x55, 0x55,    0x55, 0x55,
  79.  
  80.     0xAA, 0xAA,    0xAA, 0xAA,
  81.     0x55, 0x55,    0x55, 0x55,
  82.     0xAA, 0xAA,    0xAA, 0xAA,
  83.     0x55, 0x55,    0x55, 0x55,
  84.     0xAA, 0xAA,    0xAA, 0xAA,
  85.     0x55, 0x55,    0x55, 0x55,
  86.     0xAA, 0xAA,    0xAA, 0xAA,
  87.     0x55, 0x55,    0x55, 0x55,
  88. };
  89.  
  90.  
  91. GLfloat sdepth = 10.;
  92. float   light[3],
  93.         phi = PI / 4.0,
  94.         theta = PI / 4.0;
  95. GLfloat ctheta = -900, cphi, cvtheta, cvphi;
  96.  
  97. float fabso (float a );
  98.  
  99. /* Changes for ECLIPSE 8 bit machine */
  100. /*  don't use 7 and 8 for appearances. These are the text standards */
  101. unsigned short ECLIPSE8_RAMP[10] = {4, 5, 6, 8, 9, 10, 11, 12, 13, 14};
  102. GLboolean is_8bit;
  103. short savearray[384];
  104.  
  105. /** change for new window control */
  106. float halfwinx, halfwiny;
  107. long worgx, worgy;
  108. long wsizex, wsizey;
  109. long pikx, piky;
  110.  
  111. GLboolean follow;
  112.  
  113.  
  114. float px, py;
  115. float light[3];
  116. float cx, cy, cz, cvx, cvy, cvz;
  117. float dmr[6], fr[6];
  118.  
  119. GLfloat knee[6];
  120. GLfloat hip_phi[6];
  121. GLfloat hip_theta[6];
  122. GLboolean legup[6];
  123. float legx[6], legy[6];
  124.  
  125.  
  126. enum {
  127.     NOTHING,
  128.     FORWARD,
  129.     BACKWARD,
  130.     LEFT,
  131.     MIDDLE
  132. };
  133.  
  134. short function;
  135.  
  136.  
  137.  
  138. /*  mymakerange  -- color ramp utilities        */
  139. void
  140. mymakerange (unsigned short a, unsigned short b, GLubyte red1, GLubyte red2,
  141.     GLubyte  green1, GLubyte green2, GLubyte blue1, GLubyte blue2)
  142. {
  143.     float   i;
  144.     int     j;
  145.     float   dr,
  146.             dg,
  147.             db;
  148.  
  149.     i = (float) (b - a);
  150.     dr = (float) (red2 - red1) / i;
  151.     dg = (float) (green2 - green1) / i;
  152.     db = (float) (blue2 - blue1) / i;
  153.  
  154.     for (j = 0; j <= (int) i; j++)
  155.     mapcolor ((unsigned short) j + a,
  156.         (short) (dr * (float) j + red1),
  157.         (short) (dg * (float) j + green1),
  158.         (short) (db * (float) j + blue1));
  159. /*    mapcolor ((unsigned short) j + a,
  160.         (GLubyte) (dr * (float) j + red1),
  161.         (GLubyte) (dg * (float) j + green1),
  162.         (GLubyte) (db * (float) j + blue1));
  163. */
  164. }
  165.  
  166.  
  167. /*  Set up Eclipse 8 bit color ramp */
  168.  
  169.  
  170. void
  171. make_eclipse8_range(unsigned short e_ramp[], int red1, int red2,
  172.                     int green1, int green2, int blue1, int blue2)
  173. {
  174.     int i;
  175.     float rinc, ginc, binc;
  176.  
  177.     rinc = (float)(red2 - red1) / (float)ECLIPSE8_NCOLORS;
  178.     ginc = (float)(green2 - green1) / (float)ECLIPSE8_NCOLORS;
  179.     binc = (float)(blue2 - blue1) / (float)ECLIPSE8_NCOLORS;
  180.  
  181.     for (i = 0; i < ECLIPSE8_NCOLORS; i++) {
  182.     mapcolor(e_ramp[i],
  183.         (short)(i * rinc + red1),
  184.         (short)(i * ginc + green1),
  185.         (short)(i * binc + blue1));
  186.     }
  187. }
  188.  
  189.  
  190. /*  setupcolors  -- load color map        */
  191.  
  192. /* Changed for ECLIPSE 8 bit machine */
  193. void
  194. setupcolors (void) {
  195.     if (!is_8bit) {
  196.     mapcolor (GRAY, 128, 128, 128);
  197.     mapcolor (GRID, 128, 200, 250);
  198.     mapcolor (SKYBLUE, 50, 50, 150);
  199.     mymakerange (RAMPB5, RAMPE5, 125, 250, 125, 250, 0, 0);
  200.     mymakerange (RAMPB4, RAMPE4, 100, 200, 125, 250, 0, 0);
  201.     mymakerange (RAMPB3, RAMPE3, 75, 150, 125, 250, 0, 0);
  202.     mymakerange (RAMPB2, RAMPE2, 50, 100, 125, 250, 0, 0);
  203.     mymakerange (RAMPB, RAMPE, 25, 50, 125, 250, 0, 0);
  204.     } else {
  205.     mapcolor (ECLIPSE8_GRAY, 128, 128, 128);
  206.     mapcolor (ECLIPSE8_GRID, 128, 200, 250);
  207.     mapcolor (ECLIPSE8_SKYBLUE, 50, 50, 150);
  208. /*
  209.     mapcolor (BLACK, 0, 0, 0);
  210.     mapcolor (COLORS, 255, 0, 0);
  211.     mapcolor (COLOR1, 0, 255, 0);
  212.     mapcolor (COLOR2, 255, 255, 0);
  213. */
  214.     make_eclipse8_range(ECLIPSE8_RAMP, 25, 250, 125, 250, 0, 0);
  215.     }
  216. }
  217.  
  218.  
  219. /**** New routines for ECLIPSE 8 bit machine */
  220.  
  221. /* reduces color index value to the lower 16 indices in the color table
  222.     see ECLIPSE8_RAMP[] for which entries are used for ramp */
  223.  
  224. short
  225. reduce_index (short c)
  226. {
  227.     c = c - RAMPB + 4;
  228.     while (c > 13)
  229.     c -= 10;
  230.     if (c > 6)
  231.     c++;
  232.     return(c);
  233. }
  234.  
  235.  
  236. void
  237. getcoords (void)
  238. {
  239.     pikx = getvaluator(MOUSEX);
  240.     piky = getvaluator(MOUSEY);
  241.     if (pikx <= worgx || pikx >= worgx + wsizex || 
  242.     piky <= worgy || piky >= worgy + wsizey) {
  243.     pikx = worgx + wsizex / 2 + 1;
  244.     piky = worgy + wsizey / 2 + 1;
  245.     }
  246. }
  247.  
  248.  
  249. static void
  250. getMouseCoords (void) {
  251.     GLint x, y;
  252.  
  253.     tkGetMouseLoc (&x, &y);
  254.     pikx = x;
  255.     piky = wsizey - y;
  256.     if ( (pikx < 0) || (pikx > wsizex) ||
  257.           (piky < 0) || (piky > wsizey) ) {
  258.         pikx = wsizex / 2 + 1;
  259.         piky = wsizey / 2 + 1;
  260.     }
  261. }
  262.  
  263.  
  264. int
  265. l05 (int i)
  266. {
  267.     if (i < 0)
  268.     return (i + 6);
  269.     if (i > 5)
  270.     return (i - 6);
  271.     return (i);
  272. }
  273.  
  274.  
  275. int
  276. sgn (float i)
  277. {
  278.     if (i < 0)
  279.     return (-1);
  280.     if (i > 0)
  281.     return (1);
  282.     return (0);
  283. }
  284.  
  285.  
  286. static void
  287. fixWindow (void) {
  288.     halfwinx = (float)wsizex / 2.0;
  289.     halfwiny = (float)wsizey / 2.0;
  290.  
  291.     glViewport (0, 0, wsizex, wsizey);
  292.     glPopMatrix();
  293.     glPushMatrix();
  294.     gluPerspective (80, wsizex / (float) wsizey, 0.01, 131072);
  295. }
  296.  
  297.  
  298. /*  draw_shadow  -- draw halftone shape of insect onto the floor  */
  299. void
  300. draw_shadow (void) {
  301.     int     leg;
  302.  
  303.     glPushMatrix ();
  304.     glCallList (shadow);
  305.  
  306.     glEnable (GL_POLYGON_STIPPLE);
  307.     glTranslatef (px, py, 1.0);
  308.     glCallList (body_shadow);
  309.     for (leg = 0; leg < 6; leg++) {
  310.     glPushMatrix ();
  311. /*
  312.     glRotatef ((GLfloat) (-leg * 600), 0, 0, 1);
  313. */
  314.     glRotatef ((GLfloat) (-leg * 60), 0, 0, 1);
  315.     glTranslatef (0.0, 0.5, 0.0);
  316.     glCallList (hip_shadow);
  317. /*
  318.     glRotatef (hip_phi[leg], 0, 0, 1);
  319.     glRotatef (hip_theta[leg], 1, 0, 0);
  320. */
  321.     glRotatef (hip_phi[leg] / 10, 0, 0, 1);
  322.     glRotatef (hip_theta[leg]/10, 1, 0, 0);
  323.     glCallList (thigh_shadow);
  324.     glCallList (kneeball_shadow);
  325.     glTranslatef (0.0, 1.0, 0.0);
  326. /*
  327.     glRotatef (knee[leg], 1, 0, 0);
  328. */
  329.     glRotatef (knee[leg]/10, 1, 0, 0);
  330.     glCallList (shin_shadow);
  331.     glPopMatrix ();
  332.     }
  333.  
  334.     glDisable (GL_POLYGON_STIPPLE);
  335.     glPopMatrix ();
  336. }
  337.  
  338.  
  339. /*  draw_hind  -- draw a rear leg.  First draw hip, then shin, then thigh
  340.     and knee joint            */
  341. void
  342. draw_hind (int leg)
  343. {
  344.     glPushMatrix ();
  345. /*
  346.     glRotatef ((GLfloat) (-leg * 600), 0, 0, 1);
  347. */
  348.     glRotatef ((GLfloat) (-leg * 60), 0, 0, 1);
  349.     glTranslatef (0.0, 0.5, 0.0);
  350.     glCallList (hip[leg]);
  351. /*
  352.     glRotatef (hip_phi[leg], 0, 0, 1);
  353.     glRotatef (hip_theta[leg], 1, 0, 0);
  354. */
  355.     glRotatef (hip_phi[leg]/10, 0, 0, 1);
  356.     glRotatef (hip_theta[leg]/10, 1, 0, 0);
  357.     glPushMatrix ();        /* draw thigh */
  358.     glTranslatef (0.0, 1.0, 0.0);
  359. /*
  360.     glRotatef (knee[leg], 1, 0, 0);
  361. */
  362.     glRotatef (knee[leg]/10, 1, 0, 0);
  363.     glCallList (shin[leg]);
  364.     glPopMatrix ();
  365.     if (cz < -5.0) {
  366.     glCallList (kneeball[leg]);
  367.     glCallList (thigh[leg]);
  368.     }
  369.     else {
  370.     glCallList (kneeball[leg]);
  371.     glCallList (thigh[leg]);
  372.     }
  373.     glPopMatrix ();
  374. }
  375.  
  376.  
  377. /*  draw_fore  -- draw a front leg.  First draw hip, then thigh,
  378.     knee joint and finally shin        */
  379.  
  380. void
  381. draw_fore (int leg)
  382. {
  383.     glPushMatrix ();
  384. /*
  385.     glRotatef ((GLfloat) (-leg * 600), 0, 0, 1);
  386. */
  387.     glRotatef ((GLfloat) (-leg * 60), 0, 0, 1);
  388.     glTranslatef (0.0, 0.5, 0.0);
  389.     glCallList (hip[leg]);
  390. /*
  391.     glRotatef (hip_phi[leg], 0, 0, 1);
  392.     glRotatef (hip_theta[leg], 1, 0, 0);
  393. */
  394.     glRotatef (hip_phi[leg]/10, 0, 0, 1);
  395.     glRotatef (hip_theta[leg]/10, 1, 0, 0);
  396.     glCallList (thigh[leg]);
  397.     glCallList (kneeball[leg]);
  398.     glTranslatef (0.0, 1.0, 0.0);
  399. /*
  400.     glRotatef (knee[leg], 1, 0, 0);
  401. */
  402.     glRotatef (knee[leg]/10, 1, 0, 0);
  403.     glCallList (shin[leg]);
  404.     glPopMatrix ();
  405. }
  406.  
  407.  
  408. /*  draw_insect  -- draw rear legs, body and forelegs of insect 
  409.     the order of drawing the objects is important to 
  410.     insure proper hidden surface elimination -- painter's algorithm    */
  411. void
  412. draw_insect (void) {
  413.     GLfloat a;
  414.     float   o;
  415.     int     order;
  416.  
  417.     o = atan2 (cy + py, cx + px) + PI - (PI / 3.0);
  418.     order = l05 ((int) integer (o / (PI / 3.0)));
  419.     glPushMatrix ();        /* world */
  420.     glTranslatef (px, py, 1.0);
  421.     draw_hind (l05 (3 - order));
  422.     draw_hind (l05 (4 - order));
  423.     draw_hind (l05 (2 - order));
  424.     glCallList (body);
  425.     draw_fore (l05 (5 - order));
  426.     draw_fore (l05 (1 - order));
  427.     draw_fore (l05 (0 - order));
  428.     glPopMatrix ();
  429. }
  430.  
  431.  
  432. /*  spin_scene  -- poll input devices, keyboard and mouse
  433.     move eye position based upon user input            */
  434.  
  435. void
  436. spin_scene (void) {
  437.     float   sin1,
  438.             cos1,
  439.             sin2,
  440.             cos2,
  441.             t;
  442.     int     mx,
  443.             my;
  444.  
  445.  
  446.     /* big change to keep movement relative to window */
  447.     /* check if still in window x and y are globals - see getcoords */
  448. /*
  449.     getcoords ();
  450.     mx = 64 * ((pikx - worgx) - (wsizex / 2)) / wsizex;
  451.     my = 64 * ((piky - worgy) - (wsizey / 2)) / wsizey;
  452. */
  453.  
  454.     getMouseCoords();
  455.     mx = 64 * (pikx - (wsizex/2)) / wsizex;
  456.     my = 64 * (piky - (wsizey/2)) / wsizey;
  457.  
  458.  
  459. /*
  460.     mx = (getvaluator (MOUSEX) - 640) / 16;
  461.     my = (getvaluator (MOUSEY) - 512) / 16;
  462. */
  463.  
  464.     switch (function) {
  465.       case BACKWARD:
  466.     gl_sincos (ctheta, &sin1, &cos1);
  467.     gl_sincos (cphi, &sin2, &cos2);
  468.     cvz -= cos1;
  469.     cvx -= sin2 * sin1;
  470.     cvy -= cos2 * sin1;
  471.     function = NOTHING;
  472.         break;
  473.       case FORWARD:
  474.     gl_sincos (ctheta, &sin1, &cos1);
  475.     gl_sincos (cphi, &sin2, &cos2);
  476.     cvz += cos1;
  477.     cvx += sin2 * sin1;
  478.     cvy += cos2 * sin1;
  479.     function = NOTHING;
  480.     break;
  481.       case LEFT:
  482.     cvz = (float) - my;
  483.     gl_sincos (cphi, &sin1, &cos1);
  484.     cvx = cos1 * (float) (-mx);
  485.     cvy = -sin1 * (float) (-mx);
  486.     break;
  487.       default:
  488.     cvx = cvx * 0.7;
  489.     cvy = cvy * 0.7;
  490.     cvz = cvz * 0.7;
  491.     break;
  492.     }
  493.  
  494.     if (function == MIDDLE) {
  495.     cvtheta = my;
  496.     cvphi = mx;
  497.     }
  498.     else {
  499.     cvtheta += -cvtheta / 4;
  500.     if ((cvtheta < 4) && (cvtheta > -4))
  501.         cvtheta = 0;
  502.     cvphi += -cvphi / 4;
  503.     if ((cvphi < 4) && (cvphi > -4))
  504.         cvphi = 0;
  505.     if (function != LEFT) function = NOTHING;
  506.     }
  507.  
  508.     cx += cvx * 0.0078125;
  509.     cy += cvy * 0.0078125;
  510.     if (cz > 0.0) {
  511.     cz = 0.0;
  512.     cvz = 0.0;
  513.     }
  514.     else
  515.     cz += cvz * 0.0078125;
  516.     ctheta += cvtheta;
  517.     cphi += cvphi;
  518. }
  519.  
  520.  
  521. GLfloat degrees (float a)
  522. {
  523.     return ((GLfloat) (a * 1800.0 / PI));
  524. }
  525.  
  526.  
  527. void
  528. getstuff (void) {
  529.     int     x,
  530.             y,
  531.             i;
  532.     int     tr;
  533.  
  534.     legup[0] = GL_FALSE;
  535.     legup[2] = GL_FALSE;
  536.     legup[4] = GL_FALSE;
  537.     legup[1] = GL_TRUE;
  538.     legup[3] = GL_TRUE;
  539.     legup[5] = GL_TRUE;
  540.  
  541.     px = 0.0;
  542.     py = 0.0;
  543.     for (i = 0; i < 6; i++) {
  544.     legx[i] = 30.0 / 2.0 + (float) i;
  545.     legy[i] = 30.0 / 2.0 + (float) i;
  546.     }
  547. }
  548.  
  549.  
  550. void
  551. dolegs (void) {
  552.     int     i;
  553.     float   r,
  554.             l,
  555.             gx,
  556.             gy,
  557.             k,
  558.             t,
  559.             a,
  560.             ux,
  561.             uy;
  562.     int     leg,
  563.             tr;
  564.  
  565.     for (leg = 0; leg < 6; leg++) {
  566.     gx = legx[leg] - 30.0 / 2.0;
  567.     gy = legy[leg] - 30.0 / 2.0;
  568.     ux = gx / (30.0 / 2.0);
  569.     uy = gy / (30.0 / 2.0);
  570.  
  571.     switch (leg) {
  572.         case 0: 
  573.         gx += 0.0;
  574.         gy += 30.0;
  575.         break;
  576.         case 1: 
  577.         gx += (30.0 * 0.8660254);
  578.         gy += (30.0 * 0.5);
  579.         break;
  580.         case 2: 
  581.         gx += (30.0 * 0.8660254);
  582.         gy += (30.0 * -0.5);
  583.         break;
  584.         case 3: 
  585.         gx += 0.0;
  586.         gy += -30.0;
  587.         break;
  588.         case 4: 
  589.         gx += (30.0 * -0.8660254);
  590.         gy += (30.0 * -0.5);;
  591.         break;
  592.         case 5: 
  593.         gx += (30.0 * -0.8660254);
  594.         gy += (30.0 * 0.5);
  595.         break;
  596.     }
  597.     r = sqrt ((gx * gx) + (gy * gy)) / 30.0;
  598.     l = sqrt (1.0 + (r * r));
  599.     k = acos ((5.0 - (l * l)) / 4.0);
  600.  
  601.     knee[leg] = (GLfloat) degrees (k);
  602.  
  603.     t = (2.0 * sin (k)) / l;
  604.     if (t > 1.0)
  605.         t = 1.0;
  606.  
  607.     a = asin (t);
  608.     if (l < 1.7320508)
  609.         a = PI - a;
  610.  
  611.     hip_theta[leg] =
  612.         (GLfloat) (degrees (a - atan2 (1.0, r)));
  613.  
  614.     if (gx == 0.0) {
  615.         hip_phi[leg] = (GLfloat) (900 * sgn (gy));
  616.     }
  617.     else {
  618.         hip_phi[leg] = (GLfloat) (degrees (atan2 (gy, gx)));
  619.     }
  620.     hip_phi[leg] += (-900 + 600 * leg);
  621.  
  622.     if (legup[leg]) {
  623.         hip_theta[leg] += (GLfloat)
  624.         (200.0 * ((fr[leg] / 2.0) - fabso (dmr[leg] - (fr[leg] / 2.0))));
  625.     }
  626.     }
  627. }
  628.  
  629.  
  630. void
  631. move_insect (void) {
  632.     register int    i;
  633.     register float  mx,
  634.                     my,
  635.                     vx,
  636.                     vy,
  637.                     dx,
  638.                     dy,
  639.                     dr,
  640.                     lx,
  641.                     ly,
  642.                     lr,
  643.                     dmx,
  644.                     dmy;
  645.     float   s,
  646.             c;
  647.  
  648. /*  mx = (float) getvaluator (MOUSEX) / 640.0 - 1.0;
  649.     my = (float) getvaluator (MOUSEY) / 512.0 - 1.0;
  650. */
  651.  
  652. /* changed to keep input within the window.
  653.  x and y are globals - see getcoords */
  654. /*
  655.     getcoords ();
  656.     mx = ((float)pikx - (float)worgx) / halfwinx - 1.0;
  657.     my = ((float)piky - (float)worgy) / halfwiny - 1.0;
  658. */
  659.     getMouseCoords();
  660.     mx = pikx / halfwinx - 1.0; 
  661.     my = piky / halfwiny - 1.0;
  662.  
  663.  
  664.  
  665.     gl_sincos (cphi, &s, &c);
  666.     dx = mx * c + my * s;
  667.     dy = -mx * s + my * c;
  668.     mx = dx;
  669.     my = dy;
  670.  
  671.     px += mx / (float) (RES);
  672.     py += my / (float) (RES);
  673.  
  674.     if (follow) {
  675.     cx -= mx / (float) (RES);
  676.     cy -= my / (float) (RES);
  677.     }
  678.  
  679.     dr = sqrt (mx * mx + my * my);
  680.     dx = mx / dr;
  681.     dy = my / dr;
  682.  
  683.     for (i = 0; i < 6; i++) {
  684.     lx = legx[i] - (float) (RES / 2);
  685.     ly = legy[i] - (float) (RES / 2);
  686.     lr = (float) (RES / 2);
  687.     lx = lx / lr;
  688.     ly = ly / lr;
  689.     dmx = (dx - lx);
  690.     dmy = (dy - ly);
  691.     dmr[i] = sqrt (dmx * dmx + dmy * dmy);
  692.     if (legup[i]) {
  693.         dmx = 3 * dr * dmx / dmr[i];
  694.         dmy = 3 * dr * dmy / dmr[i];
  695.         legx[i] += dmx;
  696.         legy[i] += dmy;
  697.         if ((dmr[i]) < 0.15) {
  698.         legup[i] = GL_FALSE;
  699.         }
  700.     }
  701.     else {
  702.         legx[i] -= mx;
  703.         legy[i] -= my;
  704.  
  705.         if (!legup[l05 (i - 1)] && !legup[l05 (i + 1)] &&
  706.             (dmr[i] > REACH) &&
  707.             ((lx * dx + ly * dy) < 0.0)) {
  708.         legup[i] = GL_TRUE;
  709.         fr[i] = dmr[i];
  710.         legx[i] += dmx;
  711.         legy[i] += dmy;
  712.         }
  713.     }
  714.     }
  715. }
  716.  
  717.  
  718. void
  719. rotate60 (char c, int n, GLfloat a[][3])
  720. {
  721.     int     i,
  722.             j,
  723.             l;
  724.     float   nx,
  725.             ny;
  726.  
  727.     switch (c) {
  728.     case 'z': 
  729.         i = 0;
  730.         j = 1;
  731.         break;
  732.     case 'y': 
  733.         i = 2;
  734.         j = 0;
  735.         break;
  736.     case 'x': 
  737.         i = 1;
  738.         j = 2;
  739.         break;
  740.     };
  741.     for (l = 0; l < n; l++) {
  742.     nx = a[l][i] * COS60 - a[l][j] * SIN60;
  743.     ny = a[l][i] * SIN60 + a[l][j] * COS60;
  744.     a[l][i] = nx;
  745.     a[l][j] = ny;
  746.     }
  747. }
  748.  
  749.  
  750. void
  751. getpolycolor (int p, float pts[][3])
  752. {
  753.     float   norm[3];
  754.     float   v1[3],
  755.             v2[3],
  756.             cons;
  757.     int     i,
  758.             get;
  759.     float   c;
  760.  
  761.     for (i = 0; i < 3; i++)
  762.     norm[i] = 0.0;
  763.     i = 0;
  764.     get = 1;
  765.     i = 1;
  766.     v1[0] = pts[1][0] - pts[0][0];
  767.     v1[1] = pts[1][1] - pts[0][1];
  768.     v1[2] = pts[1][2] - pts[0][2];
  769.  
  770.     v2[0] = pts[2][0] - pts[0][0];
  771.     v2[1] = pts[2][1] - pts[0][1];
  772.     v2[2] = pts[2][2] - pts[0][2];
  773.  
  774.     norm[0] = v1[1] * v2[2] - v1[2] * v2[1];
  775.     norm[1] = v1[2] * v2[0] - v1[0] * v2[2];
  776.     norm[2] = v1[0] * v2[1] - v1[1] * v2[0];
  777.  
  778.     cons = sqrt ((norm[0] * norm[0]) +
  779.         (norm[1] * norm[1]) + (norm[2] * norm[2]));
  780.     for (i = 0; i < 3; i++)
  781.     norm[i] = norm[i] / cons;
  782.  
  783.     c = dot (norm, light);
  784.     if (c < 0.0)
  785.     c = 0.0;
  786.     if (c > 1.0)
  787.     c = 1.0;
  788.     switch (p) {
  789.     case 0: 
  790.         c = (float) (RAMPE - RAMPB) * c + (float) (RAMPB);
  791.             if (((unsigned short) c) > RAMPE) c = (float) RAMPE;
  792. #ifdef FLAT_SHADING
  793.         c = COLOR1;
  794. #endif
  795.         break;
  796.     case 1: 
  797.         c = (float) (RAMPE2 - RAMPB2) * c + (float) (RAMPB2);
  798.             if (((unsigned short) c) > RAMPE2) c = (float) RAMPE2;
  799. #ifdef FLAT_SHADING
  800.             c = COLOR2;
  801. #endif
  802.         break;
  803.     case 2: 
  804.         c = (float) (RAMPE3 - RAMPB3) * c + (float) (RAMPB3);
  805.             if (((unsigned short) c) > RAMPE3) c = (float) RAMPE3;
  806. #ifdef FLAT_SHADING
  807.             c = COLOR2;
  808. #endif
  809.         break;
  810.     case 3: 
  811.         c = (float) (RAMPE4 - RAMPB4) * c + (float) (RAMPB4);
  812.             if (((unsigned short) c) > RAMPE4) c = (float) RAMPE4;
  813. #ifdef FLAT_SHADING
  814.             c = COLOR2;
  815. #endif
  816.         break;
  817.     case 4: 
  818.         c = (float) (RAMPE5 - RAMPB5) * c + (float) (RAMPB5);
  819.             if (((unsigned short) c) > RAMPE5) c = (float) RAMPE5;
  820. #ifdef FLAT_SHADING
  821.             c = COLOR2;
  822. #endif
  823.         break;
  824.     }
  825.  
  826.     /* Changed for 8 bit ECLIPSE machine */
  827.     if (is_8bit)
  828.     c = (float)reduce_index((int)c);
  829.     glIndexi (c);    
  830. }
  831.  
  832.  
  833. GLboolean
  834. lit (int p, float pts[][3])
  835. {
  836.     float   norm[3];
  837.     float   v1[3],
  838.             v2[3],
  839.             cons;
  840.     int     i,
  841.             get;
  842.     float   c;
  843.  
  844.     for (i = 0; i < 3; i++)
  845.     norm[i] = 0.0;
  846.     i = 0;
  847.     get = 1;
  848.     i = 1;
  849.     v1[0] = pts[1][0] - pts[0][0];
  850.     v1[1] = pts[1][1] - pts[0][1];
  851.     v1[2] = pts[1][2] - pts[0][2];
  852.  
  853.     v2[0] = pts[2][0] - pts[0][0];
  854.     v2[1] = pts[2][1] - pts[0][1];
  855.     v2[2] = pts[2][2] - pts[0][2];
  856.  
  857.     norm[0] = v1[1] * v2[2] - v1[2] * v2[1];
  858.     norm[1] = v1[2] * v2[0] - v1[0] * v2[2];
  859.     norm[2] = v1[0] * v2[1] - v1[1] * v2[0];
  860.  
  861.     cons = sqrt ((norm[0] * norm[0]) +
  862.         (norm[1] * norm[1]) + (norm[2] * norm[2]));
  863.     for (i = 0; i < 3; i++)
  864.     norm[i] = norm[i] / cons;
  865.  
  866.     c = dot (norm, light);
  867.     return (c > 0.0);
  868. }
  869.  
  870.  
  871. float   dot (float vec1[3], float vec2[3])
  872. {
  873.     float   xx;
  874.     xx = (vec1[1] * vec2[1])
  875.     + (vec1[2] * vec2[2])
  876.     + (vec1[0] * vec2[0]);
  877.     return ((float) xx);
  878. }
  879.  
  880.  
  881. void 
  882. getlightvector (void) {
  883.     float   f;
  884.     light[2] = cos (theta);
  885.     f = sin (theta);
  886.     light[1] = -sin (phi) * f;
  887.     light[0] = -cos (phi) * f;
  888. }
  889.  
  890.  
  891. float   integer (float x)
  892. {
  893.     if (x < 0.0)
  894.     x -= 1.0;
  895.     x = (float) (int) x;
  896.     return (x);
  897. }
  898.  
  899.  
  900. float   frac (float x)
  901. {
  902.     return (x - integer (x));
  903. }
  904.  
  905.  
  906. float
  907. fabso (float x)
  908. {
  909.     if (x < 0.0)
  910.     return (-x);
  911.     else
  912.     return (x);
  913. }
  914.  
  915.  
  916. void
  917. drawAll (void) {
  918.    /* new for ECLIPSE 8 bit version */
  919.    if (is_8bit)
  920.       glClearIndex (ECLIPSE8_SKYBLUE);
  921.    else
  922.       glClearIndex (SKYBLUE);
  923.  
  924.    glClear (GL_COLOR_BUFFER_BIT);
  925.    glPushMatrix();
  926.    doViewit();
  927.    glCallList (screen);
  928.    draw_shadow();
  929.    draw_insect();
  930.    glPopMatrix();
  931. }
  932.  
  933.  
  934. static void Reshape(int width, int height)
  935. {
  936.  
  937.       wsizex = width;
  938.       wsizey = height;
  939.       fixWindow();
  940. }
  941.  
  942. static GLenum Key(int key, GLenum mask)
  943. {
  944.       switch (key) {
  945.         case TK_ESCAPE:
  946.           tkQuit();
  947.           break;
  948.     case TK_A:
  949.     case TK_a:
  950.       function = FORWARD;
  951.       break;
  952.     case TK_Z:
  953.     case TK_z:
  954.       function = BACKWARD;
  955.       break;
  956.     case TK_F:
  957.     case TK_f:
  958.       follow = !follow;
  959.       break;
  960.         default:
  961.           return GL_FALSE;
  962.       }
  963.       return GL_TRUE;
  964. }
  965.  
  966. static GLenum MouseUp(int mouseX, int mouseY, GLenum button)
  967. {
  968.     switch (button) {
  969.       case TK_LEFTBUTTON:
  970.         function = NOTHING;
  971.         break;
  972.       case TK_MIDDLEBUTTON:
  973.         function = NOTHING;
  974.         break;
  975.       default:
  976.         return GL_FALSE;
  977.     }
  978.       return GL_TRUE;
  979. }
  980.  
  981. static GLenum MouseDown(int mouseX, int mouseY, GLenum button)
  982. {
  983.  
  984.     switch (button) {
  985.       case TK_LEFTBUTTON:
  986.         function = LEFT;
  987.         break;
  988.       case TK_MIDDLEBUTTON:
  989.         function = MIDDLE;
  990.         break;
  991.       default:
  992.         return GL_FALSE;
  993.     }
  994.       return GL_TRUE;
  995. }
  996.  
  997. static void animate (void) {
  998.       spin_scene();
  999.       move_insect();
  1000.       dolegs();
  1001.       drawAll();
  1002.       tkSwapBuffers();
  1003. }
  1004.  
  1005.  
  1006.  
  1007. /*    main routine -- handle tokens of window manager
  1008.         -- display shadow and insect
  1009. */
  1010.  
  1011. void
  1012. main (int argc, char *argv[]) {
  1013.     int     i,
  1014.             j,
  1015.             k;
  1016.     short   dev,
  1017.             val;
  1018.     long    nplanes;
  1019.     GLboolean attached;
  1020.  
  1021.  
  1022.     follow = GL_TRUE;
  1023.     wsizex = 500;
  1024.     wsizey = 400;
  1025.     worgx = 252;
  1026.     worgy = 184;
  1027.  
  1028.     tkInitPosition(0, 0, wsizex, wsizey);
  1029.  
  1030.     tkInitDisplayMode(TK_INDEX|TK_DOUBLE|TK_DIRECT);
  1031.  
  1032.     if (tkInitWindow("Insect") == GL_FALSE) {
  1033.         tkQuit();
  1034.     }
  1035.  
  1036.     glPolygonStipple ((unsigned char *) halftone);
  1037.     glShadeModel(GL_FLAT);
  1038.  
  1039.     getlightvector ();
  1040.  
  1041. /* Changes for ECLIPSE 8 bit machine */
  1042.  
  1043.  
  1044.  
  1045. /*
  1046.  * Machines with enough bitplanes will use colormap entries CMAPSTART
  1047.  * to CMAPSTART+127.  If the machine doesn't have enough bitplanes,
  1048.  * only colors 0 to 15 will be used (it is assumed that all machines
  1049.  * have at least 4 bitplanes in colormap double-buffered mode).
  1050.  */
  1051. #ifdef ECLIPSE
  1052.     nplanes = glGetI(GD_BITS_NORM_DBL_CMODE);
  1053.     /* save color map in savearray */
  1054.     if ((1<<nplanes) > (CMAPSTART+127)) {
  1055.     is_8bit = GL_FALSE;
  1056.     }
  1057.     else {
  1058.     is_8bit = GL_TRUE;
  1059.     }
  1060. #else
  1061.     nplanes = 4;
  1062.     is_8bit = GL_TRUE;
  1063. #endif
  1064.  
  1065.  
  1066.     setupcolors ();
  1067. /* initialize transformation stuff */
  1068.     cx = 0.0;
  1069.     cy = 10.0;
  1070.     cz = -2.0;
  1071.     cvx = cvy = cvz = 0.0;
  1072.     ctheta = -900;
  1073.     cphi = 0;
  1074.     cvtheta = cvphi = 0.0;
  1075.     function = NOTHING;
  1076.  
  1077.     glPushMatrix();
  1078.  
  1079.     fixWindow();
  1080.     createobjects ();
  1081.     getstuff ();
  1082.     spin_scene ();
  1083.     move_insect ();
  1084.     dolegs ();
  1085.  
  1086.     tkExposeFunc(Reshape);
  1087.     tkReshapeFunc(Reshape);
  1088.     tkKeyDownFunc(Key);
  1089.     tkMouseDownFunc(MouseDown);
  1090.     tkMouseUpFunc(MouseUp);
  1091.     tkIdleFunc(animate);
  1092.     tkExec();
  1093.  
  1094.     glPopMatrix();
  1095. }
  1096.